package com.huanxing.cloud.order.controller.app;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import com.huanxing.cloud.common.core.constant.CommonConstants;
import com.huanxing.cloud.common.core.enums.MallErrorCodeEnum;
import com.huanxing.cloud.common.core.util.Result;
import com.huanxing.cloud.common.security.util.SecurityUtils;
import com.huanxing.cloud.order.api.dto.CreateOrderDTO;
import com.huanxing.cloud.order.api.dto.OrderAppraiseDTO;
import com.huanxing.cloud.order.api.dto.PrepayDTO;
import com.huanxing.cloud.order.api.dto.SettlementOrderDTO;
import com.huanxing.cloud.order.api.entity.OrderInfo;
import com.huanxing.cloud.order.api.entity.OrderItem;
import com.huanxing.cloud.order.api.entity.OrderRefund;
import com.huanxing.cloud.order.api.enums.OrderRefundEnum;
import com.huanxing.cloud.order.api.enums.OrderStatusEnum;
import com.huanxing.cloud.order.api.vo.SettlementOrderVO;
import com.huanxing.cloud.order.service.IOrderInfoService;
import com.huanxing.cloud.order.service.IOrderItemService;
import com.huanxing.cloud.order.service.IOrderRefundService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 订单
 *
 * @author lijx
 * @since 2022/3/7 14:01
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/app/orderinfo")
@Tag(description = "app-orderinfo", name = "商城订单-API")
public class AppOrderInfoController {

	private final IOrderInfoService orderInfoService;

	private final IOrderItemService orderItemService;

	private final IOrderRefundService orderRefundService;

	@Operation(summary = "订单列表")
	@GetMapping("/page")
	public Result<IPage<OrderInfo>> page(Page page, OrderInfo orderInfo) {
		orderInfo.setUserId(SecurityUtils.getUser().getUserId());
		return Result.success(orderInfoService.apiPage(page, orderInfo));
	}

	@Operation(summary = "通过订单id查询")
	@GetMapping("/{id}")
	public Result<OrderInfo> getById(@PathVariable String id) {
		return Result.success(orderInfoService.getOrderById(id));
	}

	@Operation(summary = "结算订单")
	@PostMapping("/settlement")
	public Result<SettlementOrderVO> settlementOrder(@RequestBody SettlementOrderDTO settlementOrderDTO) {
		settlementOrderDTO.setUserId(SecurityUtils.getUser().getUserId());
		return Result.success(orderInfoService.settlementOrder(settlementOrderDTO));
	}

	@Operation(summary = "创建订单")
	@PostMapping("/create")
	public Result<List<OrderInfo>> createOrder(@RequestBody CreateOrderDTO createOrderDTO) {
		createOrderDTO.setUserId(SecurityUtils.getUser().getUserId());
		return Result.success(orderInfoService.createOrder(createOrderDTO));
	}

	@Operation(summary = "预支付")
	@PostMapping("/prepay")
	public Result<Object> prepay(@RequestBody PrepayDTO prepayDTO) {
		return orderInfoService.prepay(prepayDTO);
	}

	@Operation(summary = "订单取消")
	@GetMapping("/cancel/{id}")
	public Result<String> cancelOrder(@PathVariable String id) {
		OrderInfo orderInfo = orderInfoService.getById(id);
		if (ObjectUtil.isNull(orderInfo)) {
			return Result.fail(MallErrorCodeEnum.ERROR_60003.getCode(), MallErrorCodeEnum.ERROR_60003.getMsg());
		}
		return Result.success(orderInfoService.cancelOrder(orderInfo));
	}

	@Operation(summary = "订单删除")
	@GetMapping("/del/{id}")
	public Result<Boolean> delOrder(@PathVariable String id) {
		OrderInfo orderInfo = orderInfoService.getById(id);
		if (ObjectUtil.isNull(orderInfo)) {
			return Result.fail(MallErrorCodeEnum.ERROR_60003.getCode(), MallErrorCodeEnum.ERROR_60003.getMsg());
		}
		if (CommonConstants.YES.equals(orderInfo.getPayStatus())
				&& OrderStatusEnum.STATUS_11.getCode().equals(orderInfo.getStatus())) {
			return Result.fail(MallErrorCodeEnum.ERROR_60006.getCode(), MallErrorCodeEnum.ERROR_60006.getMsg());
		}
		orderItemService.remove(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId, id));
		return Result.success(orderInfoService.removeById(id));
	}

	@Operation(summary = "订单确认收货")
	@GetMapping("/receiver/{id}")
	public Result<Boolean> receiverOrder(@PathVariable String id) {
		OrderInfo orderInfo = orderInfoService.getById(id);
		if (ObjectUtil.isNull(orderInfo)) {
			return Result.fail(MallErrorCodeEnum.ERROR_60003.getCode(), MallErrorCodeEnum.ERROR_60003.getMsg());
		}
		// 处理确认收货
		if (!OrderStatusEnum.STATUS_3.getCode().equals(orderInfo.getStatus())) {
			return Result.fail(MallErrorCodeEnum.ERROR_60003.getCode(), MallErrorCodeEnum.ERROR_60003.getMsg());
		}
		return Result.success(orderInfoService.receiveOrder(orderInfo));
	}

	@Operation(summary = "订单评价")
	@PostMapping("/appraise/{id}")
	public Result<Boolean> appraiseOrder(@PathVariable String id,
			@RequestBody List<OrderAppraiseDTO> orderAppraiseList) {
		return Result.success(orderInfoService.appraiseOrder(id, orderAppraiseList));

	}

	@Operation(summary = "订单数量查询")
	@GetMapping("/count")
	public Result<Map<String, Long>> count(OrderInfo orderInfo) {
		orderInfo.setUserId(SecurityUtils.getUser().getUserId());
		Map<String, Long> maps = Maps.newHashMap();
		// 待付款
		maps.put(OrderStatusEnum.STATUS_1.getCode(),
				orderInfoService.count(Wrappers.lambdaQuery(orderInfo)
					.eq(OrderInfo::getStatus, OrderStatusEnum.STATUS_1.getCode())
					.eq(OrderInfo::getPayStatus, CommonConstants.NO)));
		// 待发货
		maps.put(OrderStatusEnum.STATUS_2.getCode(), orderInfoService
			.count(Wrappers.lambdaQuery(orderInfo).eq(OrderInfo::getStatus, OrderStatusEnum.STATUS_2.getCode())));
		// 待收货
		maps.put(OrderStatusEnum.STATUS_3.getCode(), orderInfoService
			.count(Wrappers.lambdaQuery(orderInfo).eq(OrderInfo::getStatus, OrderStatusEnum.STATUS_3.getCode())));
		// 待评价
		maps.put(OrderStatusEnum.STATUS_4.getCode(),
				orderInfoService.count(Wrappers.lambdaQuery(orderInfo)
					.eq(OrderInfo::getStatus, OrderStatusEnum.STATUS_4.getCode())
					.eq(OrderInfo::getAppraiseStatus, CommonConstants.NO)));
		// 退款/售后
		OrderRefund orderRefund = new OrderRefund();
		orderRefund.setUserId(orderInfo.getUserId());
		maps.put(OrderStatusEnum.STATUS_5.getCode(), orderRefundService.count(Wrappers.lambdaQuery(orderRefund)
			.in(OrderRefund::getStatus, OrderRefundEnum.STATUS_1.getCode(), OrderRefundEnum.STATUS_2.getCode())));
		return Result.success(maps);
	}

}
